package com.simple.core.dto;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.simple.core.entity.BaseEntity;
import lombok.Data;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.data.domain.Sort.Direction.ASC;
import static org.springframework.data.domain.Sort.Direction.DESC;

/**
 * 分页
 *
 * @author FanXing
 * @date 2023年03月03日 17:14
 */
@Data
public class PageDto<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    public static final Sort DEFAULT_SORT = Sort.by(DESC, BaseEntity.Fields.id);

    /**
     * 查询数据列表
     */
    private List<T> records = Collections.emptyList();

    /**
     * 总数
     */
    private long total = 0;
    /**
     * 每页显示条数，默认 10
     */
    private int size = 10;

    /**
     * 当前页
     */
    private int current = 1;

    /**
     * 排序字段信息
     */
    private List<SortDto> sorts = new ArrayList<>();

    @JsonIgnore
    public int getOffset() {
        return (current - 1) * size;
    }

    @JsonIgnore
    public int getLimit() {
        return size;
    }

    @JsonIgnore
    public Pageable getPageable() {
        List<Sort.Order> orders = getSorts().stream()
                .map(sortDto -> new Sort.Order(sortDto.isAsc() ? ASC : DESC, sortDto.getColumn()))
                .collect(Collectors.toList());
        if (orders.size() == 0) {
            orders.add(new Sort.Order(DESC, BaseEntity.Fields.id));
        }
        return PageRequest.of(getCurrent() - 1, getSize(), Sort.by(orders));
    }

    public static <T> PageDto<T> of(Page<T> page) {
        PageDto<T> pageDto = new PageDto<>();
        pageDto.setTotal(page.getTotalElements());
        pageDto.setRecords(page.getContent());
        pageDto.setSize(page.getSize());
        pageDto.setCurrent(page.getNumber() + 1);
        List<SortDto> sortDtos = page.getSort().stream().map(SortDto::of).collect(Collectors.toList());
        pageDto.setSorts(sortDtos);
        return pageDto;
    }
}
